﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Xml.Linq;

namespace OpticalPowerMeter
{
    /// <summary>
    /// 线性点组管理类
    /// </summary>
    public class LinearGroupManagement
    {
        #region 单例模式
        static LinearGroupManagement linearManagement = null;

        private LinearGroupManagement() { }

        public static LinearGroupManagement GetIntance()
        {
            if (linearManagement == null)
            {
                linearManagement = new LinearGroupManagement();
            }
            return linearManagement;
        }
        #endregion

        //配置文件保存的完整名称
        private string FileName = System.Environment.CurrentDirectory + "\\Config\\" + "LinearGroup.xml";

        private void InitFile()
        {
            string path = System.Environment.CurrentDirectory + "\\Config";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            #region 如果文件不存在，添加文件
            if (!File.Exists(FileName))
            {
                XDocument xDoc = new XDocument(
                    new XDeclaration("1.0", "UTF-8", "yes"),
                    new XElement("LinearGroups"));
                xDoc.Save(FileName);
            }
            #endregion
        }

        
        private void AddLinear(XElement parentElement, LinearPoint linearPoint)
        {
            string index = linearPoint.Index.ToString();
            string p1 = linearPoint.P1.ToString();
            string p2 = linearPoint.P2.ToString();
            parentElement.Add(new XElement("Linear",new XAttribute("Index",index),new XAttribute("P1",p1),new XAttribute("P2",p2)));
        }

        /// <summary>
        /// 保存线性组到本地
        /// </summary>
        /// <param name="groupName">线性组名称</param>
        /// <param name="linearPoints">线性清单</param>
        public void SaveGroups(string groupName,List<LinearPoint> linearPoints) {
            InitFile();
            XElement root = XElement.Load(FileName);
            XElement localGroupElement = (from element in root.Elements("LinearGroup")
                                          where element.Attribute("GroupName") != null
                                          && element.Attribute("GroupName").Value.Equals(groupName)
                                          select element
            )?.SingleOrDefault();
            #region 如果本地没有该线性组组，直接将配置信息保存
            if (localGroupElement == null)
            {
                localGroupElement = new XElement("LinearGroup", new XAttribute("GroupName", groupName));
                foreach (LinearPoint linearPoint in linearPoints)
                {
                    AddLinear(localGroupElement, linearPoint);
                }
                root.Add(localGroupElement);
                root.Save(FileName);
                return;
            }
            #endregion
            #region 如果本地有该线性组，则对比每个线性，有差异的刷新
            List<LinearPoint> localParamList = GetLinearList(groupName); //获取本地清单
            for (int i = 0; i < localParamList.Count; i++)
            {
                if (!localParamList[i].Equals(linearPoints[i]))
                {
                    localGroupElement.RemoveNodes();
                    foreach (LinearPoint linear in linearPoints)
                    {
                        AddLinear(localGroupElement, linear);
                    }
                    root.Save(FileName);
                    return;
                }
            }
            #endregion
        }

        /// <summary>
        /// 获取指定线性组的线性清单
        /// </summary>
        /// <param name="groupName">线性组名称</param>
        /// <returns>线性清单</returns>
        public List<LinearPoint> GetLinearList(string groupName)
        {
            #region 本地没有相应的配置文件，直接返回空值
            if (!File.Exists(FileName))
            {
                return null;
            }
            #endregion
            XElement root = XElement.Load(FileName);
            var result = (from element in root.Elements("LinearGroup")
                          where element.Attribute("GroupName") != null
                          && element.Attribute("GroupName").Value.Equals(groupName)
                          select element
            );
            #region 如果没有与要查询的组名相同的组，直接返回空值
            if (result.Count() == 0)
            {
                return null;
            }
            #endregion
            XElement localGroupElement = result.SingleOrDefault();
            IEnumerable<XElement> linears = localGroupElement.Elements("Linear");  //获取线性清单
            #region 获取本地线性清单，并返回
            List<LinearPoint> linearList = new List<LinearPoint>();
            foreach (XElement linearElement in linears)
            {
                int index = Convert.ToInt32(linearElement.Attribute("Index").Value);
                double p1 = Convert.ToDouble(linearElement.Attribute("P1").Value);
                double p2 = Convert.ToDouble(linearElement.Attribute("P2").Value);
                LinearPoint linearPoint = new LinearPoint();
                linearPoint.Index = index;
                linearPoint.P1 = p1;
                linearPoint.P2 = p2;
                linearList.Add(linearPoint);
            }
            return linearList;
            #endregion
        }

        /// <summary>
        /// 删除指定的线性组
        /// </summary>
        /// <param name="groupName">线性组名</param>
        public void DeleteGroup(string groupName)
        {
            if (groupName == null || groupName == "")
            {
                return;
            }
            #region 本地没有相应的配置文件，直接返回
            if (!File.Exists(FileName))
            {
                return;
            }
            #endregion
            XElement root = XElement.Load(FileName);
            var result = (from element in root.Elements("LinearGroup")
                          where element.Attribute("GroupName") != null
                          && element.Attribute("GroupName").Value.Equals(groupName)
                          select element
            );
            #region 如果没有与要查询的组名相同的组，直接返回
            if (result.Count() == 0)
            {
                return;
            }
            else
            {
                foreach (XElement groupElement in result)
                {
                    groupElement.Remove();
                }
                root.Save(FileName);
            }
            #endregion
        }

        /// <summary>
        /// 获取线性组名清单
        /// </summary>
        /// <returns>线性组名清单</returns>
        public List<string> GetLinearGroupNameList()
        {
            #region 本地没有相应的配置文件，直接返回空值
            if (!File.Exists(FileName))
            {
                return null;
            }
            #endregion
            XElement root = XElement.Load(FileName);
            IEnumerable<XElement> groupElements = root.Elements("LinearGroup");
            List<string> nameList = new List<string>();
            foreach (XElement groupElement in groupElements)
            {
                nameList.Add(groupElement.Attribute("GroupName").Value);
            }
            if (nameList.Count == 0)
            {
                return null;
            }
            return nameList;
        }
    }
}
